/*
 * Copyright (c) 2009 Nokia Corporation.
 */

/**
  * This is run after the the web page has been loaded (possibly before rendering).
  * $(document).ready documented here:
  * http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
  */
function launch() {
 $(document).ready(function() {
  try {
    console.debug("Init started.");
    var params = $.deparam.querystring();
    var db;
    if (window.openDatabase) {
        db = openDatabase("CartoonReader",
                          "1.0",
                          "CartoonReader example",
                          200000);
    }
    if (!db) {
      alert("Failed to open the database on disk.  This is probably because the version was bad or there is not enough space left in this domain's quota");
    }
    var iframeDocument = document.getElementById('cartoonContainerFrame').contentDocument;
    var content = '<html lang="en">'
      +'  <head>'
      +'    <title>CartoonReader</title>'
      +'    <link rel="stylesheet" href="../css/cartoon-view-iframe.css" type="text/css" />'
      +'  </head>'
      +'  <body>'
      +'    <article id="cartoonContainer">'
      +'      <div id="cartoonVisibleInfo">'
      +'        <h1 id="cartoonName"></h1>'
      +'        <h2 id="cartoonTitle"></h2>'
      +'        <p id="cartoonPublished"></p>'
      +'      <div class="full-stop-div"></div>'
      +'      </div>'
      +'      <img id="cartoonImage" src="../images/loading.gif" />'
      +'      <div id="cartoonInfo">'
      +'        <dl>'
      +'          <dt class="cartoonInfoHidden">Image title</dt>'
      +'          <dd id="cartoonTitleText"></dd>'
      +'          <dt class="cartoonInfoHidden">Image alt</dt>'
      +'          <dd id="cartoonAltText"></dd>'
      +'          <dt id="cartoonURLTitle">Cartoon <abbr title="Uniform Resource Locator">URL</abbr></dt>'
      +'          <dd id="cartoonURL"></dd>'
      +'        </dl>'
      +'        <button id="cartoonInfoOK">OK</button>'
      +'      </div>'
      +'    </article>'
      +'  </body>'
      +'</html>';

    iframeDocument.open();
    iframeDocument.write(content);
    iframeDocument.close();
    var backend = new CartoonManagerBackend(db);
    var cartoonContainer = $('#cartoonContainerFrame').contents().find("#cartoonContainer");
    var elements = {document: document,
                    navigation: $("nav"),
                    headerContainer: $("#headerContainer"),
                    cartoonName: cartoonContainer.end().find("#cartoonName"),
                    cartoonTitle: cartoonContainer.end().find("#cartoonTitle"),
                    cartoonImage: cartoonContainer.end().find("#cartoonImage"),
                    cartoonInfo: cartoonContainer.end().find("#cartoonInfo"),
                    cartoonTitleText: cartoonContainer.end().find("#cartoonTitleText"),
                    cartoonAltText: cartoonContainer.end().find("#cartoonAltText"),
                    cartoonPublished: cartoonContainer.end().find("#cartoonPublished"),
                    cartoonURL: cartoonContainer.end().find("#cartoonURL"),
                    images: $("img").add("#cartoonImage",cartoonContainer),
                    body: $("body"),
                    navLiButtons: $("nav li button"),
                    cartoonReader: $("#cartoonReader")};
    var params =  $.deparam.querystring();
    if(window.appWindow) {
      window.close = appWindow.close;
      window.minimize = appWindow.minimize;
    }
    var platform = "";
    if(window.platformResolver) {
      platform = window.platformResolver.platform();
    }
    var helpers = { dndHelper: new DnDHelper(),
                    cartoonDataFetcher: new CartoonDataFetcher(new FeedUpdateBroker(),
                                                               new CartoonParser())
                  };
    helpers.maemoHelper = new MaemoHelper(window,
                                          helpers.dndHelper);
    window.SingleCartoon = new SingleCartoon(elements,
                                             helpers,
                                             backend,
                                             window,
                                             params,
                                             platform);
    console.debug("Init finished.");
  }
  catch(e) {
    console.error(e);
    alert(e);
  }
 });
}

function SingleCartoon(elements,
                       helpers,
                       backend,
                       appWindow,
                       params,
                       platform) {
  this.C_MANAGE_URL = "../html/manage-cartoons-view.html";
  this.PLATFORM = platform;

  this.m_backend = backend;
  this.m_window = appWindow;
  this.m_elements = elements;
  this.m_helpers = helpers;
  this.m_params = params;

  this.m_view = new SingleCartoon.View(elements);
  var adapter = new CartoonSourceResultAdapter(this.cartoonSourceCallback());
  this.m_backend.registerGetCartoonSourceAdapter(adapter);

  var subscribers = [];
  subscribers.push(this.m_view);
  this.m_model = new SingleCartoon.Model(subscribers);
  this.setup(helpers,
             elements,
             platform);
  this.m_backend.getActiveCartoonSource();
}

SingleCartoon.prototype = {
  setup: function(helpers,
                  elements,
                  platform) {
    this.bindNextButton(elements.navigation.find("#nextButton"));
    this.bindNewestButton(elements.navigation.find("#newestButton"));
    this.bindPreviousButton(elements.navigation.find("#previousButton"));
    this.bindInfoToggleButton(elements.navigation.find("#infoToggleButton"));
    this.bindInfoToggleButton(elements.cartoonInfo.find("#cartoonInfoOK"));
    this.bindManageButton(elements.navigation.find("#manageButton"));
    this.bindExitButton(elements.navigation.find("#exitButton"));
    helpers.dndHelper.disableDragging(elements.images);
    if(platform === "MAEMO") {
      helpers.maemoHelper.createTaskSwitcher(elements.headerContainer);
      helpers.maemoHelper.setFontSizeTo(elements.body, "1.25em");
    }
  },
  cartoonSourceCallback: function() {
    var callbackObject = { that: this,
                           callback: this.receiveCartoonSource,
                           errorCallback: this.receiveError};
    return callbackObject;
  },
  cartoonCallback: function() {
    var callbackObject = {cartoonReceiver: { that: this,
                                             callback: this.receiveCartoons},
                          errorReceiver: { that: this,
                                           callback: this.receiveError}
                         };
    return callbackObject;
  },
  receiveError: function(url, error) {
    alert(error);
    this.m_view.setCartoonImageURL("../images/error-icon.png");
  },
  receiveCartoonSource: function(sources) {
    var source = sources[0];
    this.m_helpers.cartoonDataFetcher.getDataFromURL(source.getUrl(),
                                                     this.cartoonCallback());
  },
  receiveCartoons: function(cartoons) {
    this.m_model.setCartoons(cartoons);
    this.m_model.setActiveCartoonIndex(0);
    this.toggleNextPreviousVisiblity();
  },
  bindNextButton: function(nextButton) {
    var self = this;
    nextButton.click(function() { self.nextButtonClicked(); });
  },
  bindNewestButton: function(newestButton) {
    var self = this;
    newestButton.click(function() {self.newestButtonClicked(); });
  },
  bindPreviousButton: function(previousButton) {
    var self = this;
    previousButton.click(function() {self.previousButtonClicked(); });
  },
  bindInfoToggleButton: function(infoToggleButton) {
    var self = this;
    infoToggleButton.click(function() {self.infoToggleButtonClicked(); });
  },
  bindManageButton: function(manageButton) {
    var self = this;
    manageButton.click(function() {self.manageButtonClicked(); });
  },
  bindExitButton: function(exitButton) {
    var self = this;
    exitButton.click(function() {self.exitButtonClicked(); });
  },
  manageButtonClicked: function(target, event) {
    var window = this.m_window;
    var url = this.C_MANAGE_URL;
    if(this.PLATFORM !== "MAEMO" &&
       this.PLATFORM !== "SYMBIAN") {
      this.m_view.fadeOut("slow",
                          function() { window.location = url; });
    }
    else {
      $("footer").hide();
      $("#cartoonContainerFrame").hide();
      if (this.PLATFORM === "MAEMO") {
        // add a tiny delay to let the page to be rendered
        window.setTimeout(function () {window.location = url;}, 40);
      }
      else {
        window.location = url;
      }
    }
  },
  nextButtonClicked: function() {
    if(this.isAvailable({ next: true})) {
      var that = this;
      var model = this.m_model;
      var view = this.m_view;
      this.m_view.hideCartoon(true, function() {
                                      model.setActiveCartoonIndex(model.getActiveCartoonIndex()-1);
                                      that.toggleNextPreviousVisiblity();
                                      view.hideCartoon(false);
                                    });
    }
  },
  newestButtonClicked: function() {
    this.toggleNextPreviousVisiblity();
    if(this.isAvailable({ newest: true})) {
      var that = this;
      var model = this.m_model;
      var view = this.m_view;
      this.m_view.hideCartoon(true, function() {
                                      model.setActiveCartoonIndex(0);
                                      that.toggleNextPreviousVisiblity();
                                      view.hideCartoon(false);
                                    });
    }
  },
  previousButtonClicked: function() {
    this.toggleNextPreviousVisiblity();
    if(this.isAvailable({ previous: true})) {
      var that = this;
      var model = this.m_model;
      var view = this.m_view;
      this.m_view.hideCartoon(true, function() {
                                      model.setActiveCartoonIndex(model.getActiveCartoonIndex()+1);
                                      that.toggleNextPreviousVisiblity();
                                      view.hideCartoon(false);
                                    });
    }
  },
  infoToggleButtonClicked: function() {
    if(this.m_view.infoOn()) {
      this.m_view.toggleInfo(false);
    }
    else {
      this.m_view.toggleInfo(true);
    }
  },
  exitButtonClicked: function() {
    this.m_window.close();
  },
  toggleNextPreviousVisiblity: function() {
    this.m_view.hidePreviousButton(!this.isAvailable({ previous: true}), 'slow');
    this.m_view.hideNextButton(!this.isAvailable({ next: true}), 'slow');
  },
  isAvailable: function(wantedAction) {
    var returnValue = false;
    var activeCartoonIndex = this.m_model.getActiveCartoonIndex();
    var cartoonsAvailable = this.m_model.getCartoonsAvailable();
    if(wantedAction.next &&
       activeCartoonIndex-1 >= 0) {
      returnValue = true;
    }
    if(wantedAction.previous &&
       activeCartoonIndex+1 < cartoonsAvailable) {
      returnValue = true;
    }
    if(wantedAction.newest &&
       activeCartoonIndex > 0) {
      returnValue = true;
    }
    return returnValue;
  }
};

SingleCartoon.Model = function(subscribers) {
  this.m_subscribers = subscribers;
  this.m_cartoons = undefined;
  this.m_activeCartoonIndex = 0;
};

SingleCartoon.Model.prototype = {
  getCartoons: function(id) {
    return this.m_cartoons;
  },
  setCartoons: function(cartoons) {
    this.m_cartoons = cartoons;
    this.informSubscribers({ cartoons: this.m_cartoons });
  },
  getCartoonsAvailable: function() {
    var cartoonsAvailable = 0;
    if(this.m_cartoons) {
      cartoonsAvailable = this.m_cartoons.cartoons.length;
    }
    return cartoonsAvailable;
  },
  getActiveCartoonIndex: function() {
    return this.m_activeCartoonIndex;
  },
  setActiveCartoonIndex: function(activeCartoonIndex) {
    this.m_activeCartoonIndex = activeCartoonIndex;
    this.informSubscribers({ activeCartoonIndex: this.m_activeCartoonIndex,
                             activeCartoonItem: this.m_cartoons.cartoons[this.m_activeCartoonIndex]});
  },
  informSubscribers: function(changes) {
    for (var i=0; i<this.m_subscribers.length; i++) {
      this.m_subscribers[i].receiveChangedValue(changes);
    }
  }
};

SingleCartoon.View = function(elements) {
  this.m_elements = elements;
  this.m_end = 0;
  this.setup(elements);
  this.m_activeCartoonItem = undefined;
};

SingleCartoon.View.prototype = {
  setup: function(elements) {
    //this.fadeIn("slow");
  },
  fadeIn: function(speed, callback) {
    this.m_elements.body.fadeIn(speed, callback);
  },
  fadeOut: function(speed, callback) {
    this.m_elements.body.fadeOut(speed, callback);
  },
  hideCartoon: function(hide,
                        callback) {
    if(!this.cartoonHidden()) {
      this.m_elements.cartoonImage.fadeOut('slow', callback);
    }
    else {
      this.m_elements.cartoonImage.fadeIn('slow', callback);
    }
  },
  cartoonHidden: function() {
    return (this.m_elements.cartoonImage.css("display") === 'none');
  },
  hideNextButton: function(hide ,speed, callback) {
    var nextButton = this.m_elements.navigation.find("#nextButton");
    if(hide) {
      nextButton.hide(speed, callback);
    }
    else {
      nextButton.show(speed, callback);
    }
  },
  nextButtonHidden: function() {
    var nextButton = this.m_elements.navigation.find("#nextButton");
    return (nextButton.attr("display") === 'none');
  },
  hidePreviousButton: function(hide, speed, callback) {
    var previousButton = this.m_elements.navigation.find("#previousButton");
    if(hide) {
      previousButton.hide(speed, callback);
    }
    else {
      previousButton.show(speed, callback);
    }
  },
  previousButtonHidden: function() {
    var previousButton = this.m_elements.navigation.find("#previousButton");
    return (previousButton.attr("display") === 'none');
  },
  updateCartoon: function(cartoons) {
    this.setCartoonName(cartoons.title);
    this.m_end = cartoons.cartoons.length;
  },
  updateActiveCartoonItem: function(activeCartoonItem) {
    this.m_activeCartoonItem = activeCartoonItem;
    this.setCartoonTitle(activeCartoonItem.title);
    this.setCartoonTitleText(activeCartoonItem.titleText);
    this.setCartoonAltText(activeCartoonItem.altText);
    this.setCartoonPublished(activeCartoonItem.date);
    this.setCartoonURL(activeCartoonItem.URL);
    this.setCartoonImageURL(activeCartoonItem.imageURL);
  },
  updateNavigation: function(navigation,
                             itemsAvailable,
                             activeCartoonIndex) {
    this.updatePreviousButton(navigation.find("#previousButton"),
                              itemsAvailable,
                              activeCartoonIndex);
    this.updateNextButton(navigation.find("#nextButton"),
                          itemsAvailable,
                          activeCartoonIndex);
    this.updateNewestButton(navigation.find("#newestButton"),
                            itemsAvailable,
                            activeCartoonIndex);
  },
  updatePreviousButton: function(previousButton,
                                 itemsAvailable,
                                 activeCartoonIndex) {
  },
  updateNextButton: function(nextButton,
                             itemsAvailable,
                             activeCartoonIndex) {
  },
  updateNewestButton: function(newestButton,
                               itemsAvailable,
                               activeCartoonIndex) {
  },
  setCartoonName: function(name) {
    this.m_elements.cartoonName.text(name);
  },
  setCartoonTitle: function(title) {
    this.m_elements.cartoonTitle.text(title);
  },
  setCartoonTitleText: function(titleText) {
    this.m_elements.cartoonTitleText.text(titleText);
    this.m_elements.cartoonImage.attr("title", titleText);
  },
  setCartoonAltText: function(alt) {
    this.m_elements.cartoonAltText.text(alt);
    this.m_elements.cartoonImage.attr("alt", alt);
  },
  setCartoonPublished: function(date) {
    this.m_elements.cartoonPublished.text(date.toDateString());
  },
  setCartoonURL: function(url) {
    this.m_elements.cartoonURL.empty();
    this.m_elements.cartoonURL.append("<a href=\"" + url + "\">" + url + "</a>");
  },
  setCartoonImageURL: function(url) {
    this.m_elements.cartoonImage.attr("src", url);
  },
  infoOn: function() {
    return (this.m_elements.cartoonInfo.css('display') !== 'none');
  },
  toggleInfo: function(infoOn) {
    if(infoOn) {
      this.m_elements.cartoonInfo.fadeIn('slow');
    }
    else {
      this.m_elements.cartoonInfo.fadeOut('slow');
    }
  },
  receiveChangedValue: function(changes) {
    if(changes.cartoons) {
      this.updateCartoon(changes.cartoons);
    }
    if(changes.activeCartoonIndex !=  undefined &&
       changes.activeCartoonItem) {
      this.updateNavigation(this.m_elements.navigation,
                            this.m_end,
                            changes.activeCartoonIndex);
      this.updateActiveCartoonItem(changes.activeCartoonItem);
    }
  }
};

launch();